package com.fanrenqiji.modules.sys.service.impl;

import com.fanrenqiji.common.persistence.Page;
import com.fanrenqiji.common.service.BaseCommonService;
import com.fanrenqiji.common.utils.SystemAuthorizingCacheUtils;
import com.fanrenqiji.modules.sys.dao.OfficeDao;
import com.fanrenqiji.modules.sys.entity.Office;
import com.fanrenqiji.modules.sys.entity.User;
import com.fanrenqiji.modules.sys.service.OfficeService;
import com.fanrenqiji.modules.sys.utils.UserUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author lijian E-mail:ljz0721cx@163.com
 * @version 创建时间：2015年2月5日 下午4:27:19
 * @description
 * 记住将整个数据处理层标注在一个事物中
 * 如果不交给spring管理将会出现session closed
 */
@Service
@Transactional(readOnly = true,propagation=Propagation.REQUIRED)
public class OfficeCommonServiceImpl extends BaseCommonService implements OfficeService {
	@Autowired
	private OfficeDao officeDao;

	/**
	 * 获得当前用户所在的所有机构
	 */
	public List<Office> findAll() {
		return UserUtils.getOfficeList();
	}

	/**
	 * 通过ID找到对应的Office
	 */
	@Override
	public Office findById(Long id) {
		return officeDao.findOne(id);
	}
	
	/**
	 * 获得组织机构的分页
	 */
	public Page<Office> findPage(Page<Office> page, Office office,Long parentId) {
		DetachedCriteria dc = officeDao.createDetachedCriteria();
		
		// 创建office的alias
		
		
		User user = UserUtils.getUser();
		if (user.isAdmin()) {
			//只要搜索条件全部为空，则按条件Parent 查询层级结构；
			if(StringUtils.isBlank(office.getName()) && StringUtils.isBlank(office.getCode())){
				dc.createAlias("parent", "parent");
				dc.add(Restrictions.eq("parent.id", parentId));
			}
			
			if (!StringUtils.isEmpty(office.getName())) {
				dc.add(Restrictions.like("name", "%" + office.getName() + "%"));
			}
			
			if (!StringUtils.isEmpty(office.getCode())) {
				dc.add(Restrictions.like("code", "%" + office.getCode() + "%"));
			}
			
			
		} else {
			//非管理员查看权限的顶层为自己所在的机构
			Long id =user.getOffice().getId();
			//如果是系统默认，则将顶层修改为自己所在机构的最高级别
			if(parentId.equals(new Long(1))){
				if (!StringUtils.isEmpty(office.getName())) {
					dc.add(Restrictions.or(Restrictions.eq("id", id),Restrictions.like("name", "%" + office.getName() + "%")));
				}
				
				if (!StringUtils.isEmpty(office.getCode())) {
					dc.add(Restrictions.or(Restrictions.eq("id", id),Restrictions.like("code", "%" + office.getCode() + "%")));
				}
				
				if(StringUtils.isEmpty(office.getName()) && StringUtils.isEmpty(office.getCode())){
					dc.add(Restrictions.eq("id", id));
				}
				
			}else{
				//只要搜索条件全部为空，则按条件id 查询层级结构；收个层次为自己所在的组织机构
				if(StringUtils.isBlank(office.getName()) && StringUtils.isBlank(office.getCode())){
					dc.createAlias("parent", "parent");
					dc.add(Restrictions.eq("parent.id", parentId));
				}
			}
			
		if (!StringUtils.isEmpty(office.getName())) {
			dc.add(Restrictions.or(Restrictions.eq("id", id),Restrictions.like("parentIds", "%" + id + ",%")));
			dc.add(Restrictions.like("name", "%" + office.getName() + "%"));
		}
		
		if (!StringUtils.isEmpty(office.getCode())) {
			dc.add(Restrictions.or(Restrictions.eq("id", id),Restrictions.like("parentIds", "%" + id + ",%")));
			dc.add(Restrictions.like("code", "%" + office.getCode() + "%"));
		}
		
		}
		
	
		
		//dc.add(Restrictions.eq("parentId", 2));
		// 根据 type sort 和id排序
		dc.addOrder(Order.asc("grade")).addOrder(Order.asc("code"));
		
			 Page<Office>  pageOffice = officeDao.find(page, dc);
			 
		/*	for(int i=pageOffice.getList().size(); i>0;i--){
				Office tempOffice = pageOffice.getList().get(i);
				if(tempOffice.getName().contains(office.getName()) || tempOffice.getCode().contains(office.getCode())){
					
				}
				temOffice
				
			}*/
			
	
		
		return pageOffice;
	}

	/**
	 * 添加和更新机构
	 */
	@Override
	@Transactional(readOnly = false)
	public void save(Office office) {
		office.setParent(this.findById(office.getParent().getId()));
		String oldParentIds = office.getParentIds(); // 获取修改前的parentIds，用于更新子节点的parentIds
		office.setParentIds(office.getParent().getParentIds()+office.getParent().getId()+",");
		officeDao.clear();
		officeDao.save(office);
		// 更新子节点 parentIds
		List<Office> list = officeDao.findByParentIdsLike("%,"+office.getId()+",%");
		for (Office e : list){
			e.setParentIds(e.getParentIds().replace(oldParentIds, office.getParentIds()));
			e.setIsBusiness(office.getIsBusiness());
		}
		officeDao.save(list);
		SystemAuthorizingCacheUtils.removeCache(UserUtils.CACHE_OFFICE_LIST);
	}
	
	
	/**
	 * 平行结构列表 添加和更新机构  的方法
	 */
	@Override
	@Transactional(readOnly = false)
	public void saveCommon(Office office) {
		
		//设置要添加的机构级别为它的父级结构的下一个级别
		int parentGrade =  Integer.valueOf(office.getParent().getGrade());
		office.setGrade(String.valueOf(parentGrade+1));
		
		String oldParentIds = office.getParentIds(); // 获取修改前的parentIds，用于更新子节点的parentIds
		office.setParentIds(office.getParent().getParentIds()+office.getParent().getId()+",");

		officeDao.clear();
		officeDao.save(office);
		// 更新子节点 parentIds
		List<Office> list = officeDao.findByParentIdsLike("%,"+office.getId()+",%");
		for (Office e : list){
			e.setParentIds(e.getParentIds().replace(oldParentIds, office.getParentIds()));
			e.setIsBusiness(office.getIsBusiness());
		}
		officeDao.save(list);
		SystemAuthorizingCacheUtils.removeCache(UserUtils.CACHE_OFFICE_LIST);
	}


	/**
	 * 删除机构
	 */
	@Transactional(readOnly = false)
	public void delete(Long id) {
		officeDao.deleteById(id, "%,"+id+",%");
		SystemAuthorizingCacheUtils.removeCache(UserUtils.CACHE_OFFICE_LIST);
	}

	@Override
	public Office findByCode(String code) {
		return officeDao.findByCode(code);
		
	}

	@Override
	public List<Office> findByGradeAndIsBusiness(String grade, String isBusiness) {
		return officeDao.findByGradeAndIsBusiness(grade, isBusiness);
	}

	@Override
	public String getOfficeGradeById(Long officeId) {
		return officeDao.getOfficeGradeById(officeId);
	}
	
}
